#include "add_ref.hpp"

#include "qbe/src/ecs/app.hpp"

#include "qbe/src/ecs/query.hpp"

#include "qbe/src/axis/axis.hpp"
#include "qbe/src/input/input.hpp"
#include "qbe/src/select/select.hpp"
#include "qbe/src/state/state.hpp"
#include "qbe/src/undoRedo/undoRedo.hpp"
#include "qbe/src/utils/utils.hpp"

#include "qbe/src/layout/layout.hpp"

#include "qlib/all.h"

#include <QMessageBox>
#include "../../layout/layout.hpp"
#include "../../utils/kutils.h"
#include "../../utils/render_ref.h"
#include "../../utils/shader.h"
#include "../components.hpp"
#include "components.hpp"

namespace qbe::draw::AddRef {

std::vector<std::shared_ptr<qlib::Cell>> getAllCell(std::shared_ptr<qlib::Reference> ref) {
  std::vector<std::shared_ptr<qlib::Cell>> cells;
  auto cell = ref->cell;
  if (cell) {
    cells.push_back(cell);
    for (auto [e, ref] : cell->reg.view<qlib::Reference::s_ptr>().each()) {
      auto _cells = getAllCell(ref);
      for (auto j : _cells) {
        cells.push_back(j);
      }
    }
  }
  return cells;
};
void exit(ecs::Query query, state::AllModeType enter_mode) {
  if (std::get<state::EditingModeType>(enter_mode) == state::EditingModeType::AddCell) {

  } else {
    auto& param = query.get_resource<AddRefModel>();
    auto& state = query.get_resource<state::State>();
    auto& cmd = query.get_resource<layout::CellCmd>();
    auto cell = cmd.get_cell();
    auto& ecs_reg = query._world.get_registry();
    for (auto [e, node] : ecs_reg.view<RefTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      node->setAllChildren(false);
      node->children.clear();
    }
    if (param.ref) {
      param.cellList.clear();
      param.ref.reset();
      param.render_ref.reset();
    }
  }
}
void init(entt::registry& reg, ecs::Commands commands, ecs::Query query) {
  auto& state = query.get_resource<state::State>();
  state.addExitCall(state::EditingModeType::AddCell, exit);

  for (auto [e, tran] : reg.view<render::SceneTag, vsg::ref_ptr<vsg::MatrixTransform>>().each()) {
    // 创建 Switch
    auto switchObject = vsg::Switch::create();
    tran->addChild(switchObject);
    commands.spawn(RefTag{}, switchObject);
  }
}

void update(entt::registry& ecs_reg, ecs::Query query, ecs::Bus& bus, ecs::EventWriter<msg::RenderEvent> event) {
  auto& state = query.get_resource<state::State>();
  //获取当前操作的Cell
  auto& cmd = query.get_resource<layout::CellCmd>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  auto cell = cmd.get_cell();
  auto& reg = cell->reg;
  auto& cell_state = query.get_resource<layout::CellState>();

  auto& axis_t = query.get_resource<axis::Axis>();

  // 仅在模式执行
  if (state.getEditingMode() != state::EditingModeType::AddCell)
    return;

  auto& param = query.get_resource<AddRefModel>();

  {
    auto res = bus.receive<UiMessage::CancelDrawing>();
    if (!res.empty()) {
      //ESC退出逻辑
      if (param.ref) {
        for (auto [e, node] : ecs_reg.view<RefTag, vsg::ref_ptr<vsg::Switch>>().each()) {
          node->setAllChildren(false);
          node->children.clear();
        }
        param.cellList.clear();
        param.ref.reset();
        param.render_ref.reset();
        state.switchMode(state::EditingModeType::None);
        return;
      }
    }
  }

  static qlib::Vec2d begin_points;
  auto res = bus.receive<UiMessage::AddCellUi>();
  if (!res.empty()) {
    if (param.ref) {
      for (auto [e, node] : ecs_reg.view<RefTag, vsg::ref_ptr<vsg::Switch>>().each()) {
        node->setAllChildren(false);
        node->children.clear();
      }
      param.cellList.clear();
      param.ref.reset();
      param.render_ref.reset();
    }
    param.cellList = res[0].cellList;
    param.isSameFile = res[0].isSameFile;
    param.ref = res[0].ref;
    begin_points = {0, 0};
    return;
  }

  if (param.cellList.empty() && param.ref == nullptr)
    return;

  qlib::Vec2d new_points = {axis_t.real_x, axis_t.real_y};

  if (param.render_ref == nullptr) {
    if (param.ref == nullptr) {
      // 创建一个引用指向新增的单元
      auto ref = qlib::Reference::create(param.cellList[0]);
      auto all_cell = getAllCell(ref);
      for (auto i : all_cell) {
        auto currentCell = cell;
        if (i == currentCell) {
          // 显示一个简单的信息对话框
          QMessageBox::information(nullptr, QObject::tr("error"), QObject::tr("Call closed-loop, unable to call"));
          param.cellList.clear();
          param.ref.reset();
          param.render_ref.reset();
          state.switchMode(state::EditingModeType::None);
          return;
        }
      }
      param.ref = ref;
    }

    for (auto [e, node] : ecs_reg.view<RefTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      node->setAllChildren(true);
      std::shared_ptr<utils::TempRender::RenderRef> render_ref = std::make_shared<utils::TempRender::RenderRef>(param.ref, ecs_reg, query, 0);
      node->addChild(true, render_ref->switchObject);
      param.render_ref = render_ref;
    }
  }

  if (param.ref == nullptr)
    return;

  auto& hand = query.get_resource<vsg::ref_ptr<input::HandleBundle>>();
  //鼠标移动
  if (hand->mouse_move) {
    // 记录距离上一次鼠标位置的偏移
    qlib::Vec2d vec = new_points - begin_points;
    //param.ref->origin += vec;
    std::vector<std::any> graphs;
    graphs.push_back(param.ref);
    auxiliary::translateGraph(graphs, vec);
    begin_points = new_points;
    param.render_ref->translate(param.ref);
  }
  //释放鼠标左键
  if (hand->mouseReleased(1)) {
    // std::vector<std::shared_ptr<qlib::Cell>> new_cells;
    auto current_cell = query.get_resource<qlib::Cell::s_ptr>();
    auto& select_part_model = query.get_resource<qbe::select::SelectPartModel>();
    select_part_model.hover.clear();
    select_part_model.select.clear();

    // 清除预选标记
    for (auto [e] : current_cell->reg.view<qbe::select::HoverTag>().each()) {
      current_cell->reg.remove<qbe::select::HoverTag>(e);
    }
    for (auto [e] : current_cell->reg.view<qbe::select::SelectTag>().each()) {
      current_cell->reg.remove<qbe::select::SelectTag>(e);
    }
    
    auto current_lib = query.get_resource<qlib::Library::s_ptr>();

    if (current_lib) {
      auto cells = getAllCell(param.ref);
      for (auto i : cells) {
        bool is_library_exist = false;
        std::vector<std::string> name_list;
        for (auto it : current_lib->cells) {
          name_list.push_back(it->name);
          if (i == it) {
            is_library_exist = true;
          }
        }
        if (is_library_exist == false) {
          std::string new_name = auxiliary::duplicateNameVerify(i->name, name_list);
          i->name = new_name;
          // new_cells.push_back(i);
          current_lib->add(i);
        }
      }
      // for (auto new_cell : new_cells) {
      //   current_lib->add(new_cell);
      // }
    }

    auto entity = cell->reg.create();
    cell->reg.emplace<std::shared_ptr<qlib::Reference>>(entity, param.ref);

    layout_cmd.add_cell(param.ref->cell);
    layout_cmd.add<qlib::Reference::s_ptr>(entity);
    //event.send(msg::RenderEvent{msg::RenderCode::CellUpdate});  //确定后版图更新
    layout_cmd.render_update();  //确定后版图更新

    //获取undo/red0
    auto& unredoMoudel = query.get_resource<undoRedoT::UndoRedoModule>();
    unredoMoudel.start(cell);
    unredoMoudel.add(entity);
    unredoMoudel.end();

    param.cellList.clear();
    param.ref.reset();
    param.render_ref.reset();
    state.switchMode(state::EditingModeType::None);
    for (auto [e, node] : ecs_reg.view<RefTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      node->setAllChildren(false);
      node->children.clear();
    }
    cell->reg.emplace_or_replace<select::SelectTag>(entity);
    auto& sele_event_writer = query.get_event_writer<select::Event>();
    sele_event_writer.send({select::Code::SelectUpdate});
    sele_event_writer.send({select::Code::HoverUpdate});
    bus.send<qbe::UiMessage::UpdateFileLisetFromLibrary>(qbe::UiMessage::UpdateFileLisetFromLibrary{current_lib});
  }
}

void post() {}

}  // namespace qbe::draw::AddRef